package model.strategys;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.swing.JOptionPane;

import view.MainAuxiliar;

import model.cubos.Adesivo;
import model.cubos.Cor;
import model.cubos.CuboMagico;
import model.cubos.CuboMagico3x3x3;
import model.rotations.RotationsImpl;

/**
 * @author
 * Classe que contém o algoritmo básico de resolução do cubo
 */
public class AlgoritmoBasico implements MyStrategys {
	
	private CuboMagico3x3x3 cubo;
	private int passo;
	private Collection movs = new ArrayList();
	private String mensagem = "";
	private Adesivo origem;
	private Adesivo destino;
	private Adesivo origemDois;
	private Adesivo destinoDois;
	private final RotationsImpl rotacao = new RotationsImpl();
	
	
	public AlgoritmoBasico(){
	}
	
	@Override
	public void resolver(CuboMagico cubo) {
		setCubo((CuboMagico3x3x3) cubo);
		resolveMeioSuperior();
	}
	

	/** Método que retorna os movimentos necessários para resolução da etapa Cruz Branca do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	public  void resolveCruz(){
		movs.clear();

		String aux = "";
		int i = 0;
		
		Adesivo[][][] matriz = cubo.getCubo();
		int flag = 0;
		
		/*
		 * posicionar o amarelo na face superior
		 */
		
		setDestino(matriz[4][1][1]);
		while(!matriz[4][1][1].isCor(Cor.AMARELO)){
			if(matriz[1][1][1].isCor(Cor.AMARELO) || matriz[5][1][1].isCor(Cor.AMARELO) || 
				matriz[3][1][1].isCor(Cor.AMARELO)){
				rotacao.Z(cubo);
			}
			if(matriz[0][1][1].isCor(Cor.AMARELO) || matriz[2][1][1].isCor(Cor.AMARELO)){
				rotacao.X(cubo);
			}
		}		
		
		setDestino(matriz[0][1][1]);
		while(!matriz[0][1][1].isCor(Cor.AZUL)){//enquanto não houver quadrado branco na posi��o [0][0][1]
			rotacao.Y(cubo);
		}
		
		if(matriz[0][2][1].isCor(Cor.AZUL) &&  matriz[0][1][1].isCor(Cor.AZUL) && matriz[5][0][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO) &&
				(matriz[1][2][1].isCor(Cor.VERMELHO) && matriz[1][1][1].isCor(Cor.VERMELHO) && matriz[5][1][2].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)) &&
				(matriz[2][2][1].isCor(Cor.VERDE) && matriz[2][1][1].isCor(Cor.VERDE) && matriz[5][2][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO) ) &&
				(matriz[3][2][1].isCor(Cor.LARANJA) && matriz[3][1][1].isCor(Cor.LARANJA) && matriz[5][1][0].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))){
			return;
		}
		
		// não estiver pronto
		while( flag != 1){//testar se passo está completo - 1 e 2
			//etapa 3
			if(matriz[0][0][1].isCor(Cor.BRANCO) || //se existir branco em uma dessas posições
					matriz[1][0][1].isCor(Cor.BRANCO) ||
					matriz[2][0][1].isCor(Cor.BRANCO) ||
					matriz[3][0][1].isCor(Cor.BRANCO)){
							
				aux = new String();
				mensagem = new String();
				setDestino(matriz[0][0][1]);
				
				while(!matriz[0][0][1].isCor(Cor.BRANCO)){//enquanto não houver quadrado branco na posi��o [0][0][1]
					rotacao.U(cubo);
				}
				
				setDestino(matriz[0][1][2]);
				
				rotacao.F(cubo);
				
				setDestino(matriz[4][1][2]);
				
				while(matriz[4][1][2].isCor(Cor.BRANCO)){//enquanto existir quadrado branco na posi��o [4][1][2]
					rotacao.U(cubo);//movimento U
				}
				
				setDestino(matriz[4][1][2]);
				
				rotacao.R(cubo);//movimento R
			}
			//fim da etapa 3
			//***************
			//etapa 4
			else //se não existir quadrado branco em nenhuma das posições [0][0][1], [1][0][1], [2][0][1], [3][0][1] 
				if(matriz[0][1][0].isCor(Cor.BRANCO) || //verificar se existe quadrado branco nessas posições
						matriz[1][1][0].isCor(Cor.BRANCO) ||
						matriz[2][1][0].isCor(Cor.BRANCO) ||
						matriz[3][1][0].isCor(Cor.BRANCO)  ){
					setDestino(matriz[0][1][0]);
					
					while(!matriz[0][1][0].isCor(Cor.BRANCO)){//enquanto não existir quadrado branco nessas posições
						rotacao.Y(cubo);//movimento Y
					}
					
					setDestino(matriz[4][1][0]);
					
					while(matriz[4][1][0].isCor(Cor.BRANCO)){//enquanto existir quadrado branco nessas posições
						rotacao.U(cubo);//movimento U
					}	
					
					setDestino(matriz[4][1][0]);
					
					rotacao.L_(cubo);//movimento L'
				}
			//fim da ETAPA 4
			//**********************
			//etapa 5
				else
					if(matriz[0][1][2].isCor(Cor.BRANCO) ||//verificar se existe quadrado branco nessas posições
							matriz[1][1][2].isCor(Cor.BRANCO) ||
							matriz[2][1][2].isCor(Cor.BRANCO) ||
							matriz[3][1][2].isCor(Cor.BRANCO)){
						
						setDestino(matriz[3][1][2]);
						
						while(!matriz[3][1][2].isCor(Cor.BRANCO)){//enquanto não existir quadrados brancos nessas posições
							rotacao.Y(cubo);//movimento Y
						}
						
						if(matriz[4][2][1].isCor(Cor.BRANCO)){//verificar se existe quadrado branco nessas posições
							
							setDestino(matriz[4][2][1]);
							
							while(matriz[4][2][1].isCor(Cor.BRANCO)){//enquanto existir quadrado branco nessas posições
								rotacao.U(cubo);//movimento U
							}
						}
						setDestino(matriz[4][2][1]);
						
						rotacao.F(cubo);//movimento F
					}
			
			//fim da etapa 5
			//********************
			//etapa 7
					else
						if(matriz[5][0][1].isCor(Cor.BRANCO) ||//verificar se existe quadrado branco nessas posições
								matriz[5][1][0].isCor(Cor.BRANCO) ||
								matriz[5][1][2].isCor(Cor.BRANCO) ||
								matriz[5][2][1].isCor(Cor.BRANCO)){
							
							setDestino(matriz[5][0][1]);
							
							while(!matriz[5][0][1].isCor(Cor.BRANCO)){
								rotacao.D(cubo);//movimento D
							}
							
							if(matriz[4][2][1].isCor(Cor.BRANCO)){//verificar se existe quadrado branco nessas posições
								
								setDestino(matriz[4][2][1]);
								
								while(matriz[4][2][1].isCor(Cor.BRANCO)){//enquanto existir quadrado branco nessas posições
									rotacao.U(cubo);//movimento U
								}
								
							}
							
							setDestino(matriz[4][2][1]);
							
//							realizar movimento F2
							rotacao.F(cubo);//movimento F
							rotacao.F(cubo);//movimento F
							
							//fim do movimento F2
							
						}
			//fim da etapa 7
			//*********************
			//etapa 8
						else
							if(matriz[0][2][1].isCor(Cor.BRANCO) ||//verificar se existe quadrado branco nessas posições
									matriz[1][2][1].isCor(Cor.BRANCO) ||
									matriz[2][2][1].isCor(Cor.BRANCO) ||
									matriz[3][2][1].isCor(Cor.BRANCO)){
								setDestino(matriz[0][2][1]);
								
								while(!matriz[0][2][1].isCor(Cor.BRANCO)){
									rotacao.D(cubo);//movimento D	
								}
								
								setDestino(matriz[4][2][1]);
								
								while(matriz[4][2][1].isCor(Cor.BRANCO)){
									rotacao.U(cubo);//movimento U
								}
								
								rotacao.F(cubo);//movimento F
							}
			//fim da etapa 8
			//*************
			//etapa 9
			if((matriz[4][0][1].isCor(Cor.BRANCO)) &&//verificar se existe quadrado branco nessas posições
					(matriz[4][1][0].isCor(Cor.BRANCO)) &&
					(matriz[4][1][2].isCor(Cor.BRANCO)) &&
					(matriz[4][2][1].isCor(Cor.BRANCO)) ){
				
				for(int j = 0; j < 4; j++){
					setDestino(matriz[0][1][1]);
					
					switch(matriz[0][1][1].getKey()){
					case 4:
						while(!(matriz[0][0][1].isCor(Cor.AZUL) && matriz[4][2][1].isCor(Cor.BRANCO) )){
							rotacao.U(cubo);//movimento U
						}
//						realizar movimento F2
						
						rotacao.F(cubo);//movimento F
						rotacao.F(cubo);//movimento F
						break;
						
					case 13:
						while(!(matriz[0][0][1].isCor(Cor.VERMELHO) && matriz[4][2][1].isCor(Cor.BRANCO))){
							rotacao.U(cubo);//movimento U
						}
						
//						realizar movimento F2
						
						rotacao.F(cubo);//movimento F
						rotacao.F(cubo);//movimento F
						break;
						
					case 22:
						while(!(matriz[0][0][1].isCor(Cor.VERDE) && matriz[4][2][1].isCor(Cor.BRANCO))){
							rotacao.U(cubo);//movimento U
						}
//						realizar movimento F2
						
						rotacao.F(cubo);//movimento F
						rotacao.F(cubo);//movimento F
						break;
						
					case 31:
						while(!(matriz[0][0][1].isCor(Cor.LARANJA) && matriz[4][2][1].isCor(Cor.BRANCO))){
							rotacao.U(cubo);//movimento U
						}
						
//						realizar movimento F2
						rotacao.F(cubo);//movimento F
						rotacao.F(cubo);//movimento F
					}
					rotacao.Y(cubo);//movimento Y
				}
			}
			setDestino(matriz[0][1][1]);
			
			while(!matriz[0][1][1].isCor(Cor.AZUL)){
				rotacao.Y(cubo);
			}
			
			if((matriz[0][2][1].isCor(Cor.AZUL) &&  matriz[0][1][1].isCor(Cor.AZUL) && matriz[5][0][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)) &&
					(matriz[1][2][1].isCor(Cor.VERMELHO) && matriz[1][1][1].isCor(Cor.VERMELHO) && matriz[5][1][2].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)) &&
					(matriz[2][2][1].isCor(Cor.VERDE) && matriz[2][1][1].isCor(Cor.VERDE) && matriz[5][2][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)) &&
					(matriz[3][2][1].isCor(Cor.LARANJA) && matriz[3][1][1].isCor(Cor.LARANJA) && matriz[5][1][0].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))){
				
				flag = 1;
			}
			
			
		}
		return;
	}
	
	/** Método que retorna os movimentos necessários para resolução da etapa Canto Inferior do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	
	public  void resolveCantoInferior(){
		resolveCruz();
		Adesivo[][][] matriz = cubo.getCubo();
		int flag = 0;
		int j = 0;
		if(matriz[5][0][0].getKey() == 45 && matriz[5][0][2].getKey() == 47 && matriz[5][2][0].getKey() == 51 && matriz[5][2][2].getKey() == 53)
			flag = 1;
		
		while(flag != 1){
			
			//etapa1
			
			if( matriz[0][0][0].isCor(Cor.BRANCO) |//(matriz[0][0][0].getKey() >= 45 && matriz[0][0][0].getKey() <= 53)  |
					(matriz[1][0][0].isCor(Cor.BRANCO) ) |//matriz[1][0][0].getKey() >= 45 && matriz[1][0][0].getKey() <= 53) |
					(matriz[2][0][0].isCor(Cor.BRANCO) ) |//[2][0][0].getKey() >= 45 && matriz[2][0][0].getKey() <= 53) |
					(matriz[3][0][0].isCor(Cor.BRANCO) ) ){ //matriz[3][0][0].getKey() >= 45 && matriz[3][0][0].getKey() <= 53) ){
				
				setDestino(matriz[1][0][0]);
				
				while(!matriz[1][0][0].isCor(Cor.BRANCO) ){//matriz[1][0][0].getKey() < 45){//enquanto não existir quadrado brano na posi��o [1][0][0]
					rotacao.U(cubo);
				}
				
				setDestino(matriz[0][0][2]);
				
				if(matriz[0][0][2].isCor(Cor.AZUL)){//matriz[0][0][2].getKey() >= 0 && matriz[0][0][2].getKey() <= 8){
					
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.AZUL)){//matriz[0][1][1].getKey() != 4){//enquanto não existir peça azul
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
					setDestino(matriz[0][2][2]);
					
					rotacao.R(cubo);
					rotacao.U(cubo);
					rotacao.R_(cubo);
				}
				else if(matriz[0][0][2].isCor(Cor.VERMELHO)){//matriz[0][0][2].getKey() >= 9 && matriz[0][0][2].getKey() <= 17){
					
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.VERMELHO)){//matriz[0][1][1].getKey() != 13){ enquanto não for vermelho
						rotacao.E(cubo);
						rotacao.D(cubo);
					}
					setDestino(matriz[0][2][2]);
					
					rotacao.R(cubo);
					rotacao.U(cubo);
					rotacao.R_(cubo);
				}
				
				else if(matriz[0][0][2].isCor(Cor.VERDE)){//matriz[0][0][2].getKey() >= 18 && matriz[0][0][2].getKey() <= 26){
					
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.VERDE)){//matriz[0][1][1].getKey() != 22){ enquanto não for verde
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
					setDestino(matriz[0][2][2]);
					
					rotacao.R(cubo);
					rotacao.U(cubo);
					rotacao.R_(cubo);
				}
				
				else if(matriz[0][0][2].isCor(Cor.LARANJA)){//matriz[0][0][2].getKey() >= 27 && matriz[0][0][2].getKey() <= 35 ){
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.LARANJA)){//matriz[0][1][1].getKey() != 31){ enquanto não for laranja
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
					
					setDestino(matriz[0][2][2]);
					
					rotacao.R(cubo);
					rotacao.U(cubo);
					rotacao.R_(cubo);
				}
				
			}
			//fim da etapa 1
			//**************
			//etapa 2
			else if( matriz[0][0][2].isCor(Cor.BRANCO) |//(matriz[0][0][2].getKey() >= 45 && matriz[0][0][2].getKey() <= 53) |
					(matriz[1][0][2].isCor(Cor.BRANCO) )|//matriz[1][0][2].getKey() >= 45 && matriz[1][0][2].getKey() <= 53) |
					(matriz[2][0][2].isCor(Cor.BRANCO) )|//matriz[2][0][2].getKey() >= 45 && matriz[2][0][2].getKey() <= 53) |
					(matriz[3][0][2].isCor(Cor.BRANCO) ) ) {//matriz[3][0][2].getKey() >= 45 && matriz[3][0][2].getKey() <= 53) ){
				setDestino(matriz[3][0][2]);
				
				while(!matriz[3][0][2].isCor(Cor.BRANCO) ){//matriz[3][0][2].getKey() < 45){enquanto não for branca
					rotacao.U(cubo);
				}
				
				setDestino(matriz[0][0][0]);
				if( matriz[0][0][0].isCor(Cor.AZUL) ){//matriz[0][0][0].getKey() >= 0 && matriz[0][0][0].getKey() <= 8){
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.AZUL) ){//matriz[0][1][1].getKey() != 4){ enquanto não for azul
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
					
					setDestino(matriz[0][2][0]);
					
					rotacao.L_(cubo);
					rotacao.U_(cubo);
					rotacao.L(cubo);
				}
				else if(matriz[0][0][0].isCor(Cor.VERMELHO) ){//matriz[0][0][0].getKey() >= 9 && matriz[0][0][0].getKey() <= 17){
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.VERMELHO) ){//matriz[0][1][1].getKey() != 13){ //enquanto não for vermelho
						rotacao.E(cubo);
						rotacao.D(cubo);
					}
					setDestino(matriz[0][2][0]);
					
					rotacao.L_(cubo);
					rotacao.U_(cubo);
					rotacao.L(cubo);
				}
				
				else if(matriz[0][0][0].isCor(Cor.VERDE) ){//matriz[0][0][0].getKey() >= 18 && matriz[0][0][0].getKey() <= 26){
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.VERDE) ){//matriz[0][1][1].getKey() != 22){ //
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
					setDestino(matriz[0][2][0]);
					
					rotacao.L_(cubo);
					rotacao.U_(cubo);
					rotacao.L(cubo);
				}
				
				else if(matriz[0][0][0].isCor(Cor.LARANJA) ){//matriz[0][0][0].getKey() >= 27 && matriz[0][0][0].getKey() <= 35){
					setDestino(matriz[0][1][1]);
					
					while(!matriz[0][1][1].isCor(Cor.LARANJA) ){//matriz[0][1][1].getKey() != 31){ // enquanto não for laranja
						rotacao.E(cubo);
						rotacao.D(cubo);
					}
					setDestino(matriz[0][2][0]);
					
					rotacao.L_(cubo);
					rotacao.U_(cubo);
					rotacao.L(cubo);
				}
				
			}
			
			//fim da etapa 2
			//*****************
			//etapa 3
			
			else if( matriz[4][0][0].isCor(Cor.BRANCO) |//(matriz[4][0][0].getKey() >= 45 && matriz[4][0][0].getKey() <= 53) ||
					matriz[4][0][2].isCor(Cor.BRANCO) |//(matriz[4][0][2].getKey() >= 45 && matriz[4][0][2].getKey() <= 53) ||
					matriz[4][2][0].isCor(Cor.BRANCO) |//(matriz[4][2][0].getKey() >= 45 && matriz[4][2][0].getKey() <= 53) ||
					matriz[4][2][2].isCor(Cor.BRANCO) ){//(matriz[4][2][2].getKey() >= 45 && matriz[4][2][2].getKey() <= 53) ){
				setDestino(matriz[4][2][2]);
				
				while(!matriz[4][2][2].isCor(Cor.BRANCO) ){//matriz[4][2][2].getKey() < 45){//enquanto não existir quadrado branco na posi��o [4][2][2]
					rotacao.U(cubo);
				}
				
				if(matriz[5][0][2].isCor(Cor.BRANCO) ){//matriz[5][0][2].getKey() >= 45 && matriz[5][0][2].getKey() <= 53){
					setDestino(matriz[5][0][2]);
					
					while(matriz[5][0][2].isCor(Cor.BRANCO) ){//matriz[5][0][2].getKey() >= 45 && matriz[5][0][2].getKey() <= 53){//enquanto existir quadrado branco na posi��o [5][0][2]
						rotacao.E(cubo);
						rotacao.D(cubo);	
					}
				}
				
				setDestino(matriz[0][0][0]);
				
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
			}
			//fim da etapa 3
			//**************
			//etapa 4
			else if( matriz[0][2][2].isCor(Cor.BRANCO) |//(matriz[0][2][2].getKey() >= 45 && matriz[0][2][2].getKey() <= 53) ||
					matriz[1][2][2].isCor(Cor.BRANCO) |//(matriz[1][2][2].getKey() >= 45 && matriz[1][2][2].getKey() <= 53) ||
					matriz[2][2][2].isCor(Cor.BRANCO) |//(matriz[2][2][2].getKey() >= 45 && matriz[2][2][2].getKey() <= 53) ||
					matriz[3][2][2].isCor(Cor.BRANCO) ) {//(matriz[3][2][2].getKey() >= 45 && matriz[3][2][2].getKey() <= 53) ){
				setDestino(matriz[0][2][2]);
				
				while(!matriz[0][2][2].isCor(Cor.BRANCO) ){//matriz[0][2][2].getKey() < 45){//enquanto não existir quadrado branco na posi��o [0][2][2]
					rotacao.Y(cubo);
				}
				setDestino(matriz[0][2][2]);
				
				rotacao.R(cubo);
				rotacao.U_(cubo);
				rotacao.R_(cubo);
			}
			
			//fim da etapa 4
			//**************
			//etapa 5
			else if( matriz[0][2][0].isCor(Cor.BRANCO) |//(matriz[0][2][0].getKey() >= 45 && matriz[0][2][0].getKey() <= 53) ||
					matriz[1][2][0].isCor(Cor.BRANCO) |//(matriz[1][2][0].getKey() >= 45 && matriz[1][2][0].getKey() <= 53) ||
					matriz[2][2][0].isCor(Cor.BRANCO) |//(matriz[2][2][0].getKey() >= 45 && matriz[2][2][0].getKey() <= 53) ||
					matriz[3][2][0].isCor(Cor.BRANCO) ){//(matriz[3][2][0].getKey() >= 45 &&  matriz[3][2][0].getKey() <= 53) ){
				setDestino(matriz[0][2][0]);
				
				while(!matriz[0][2][0].isCor(Cor.BRANCO) ){//matriz[0][2][0].getKey() < 45){//enquanto não existir quadrado branco na posi��o [0][2][0]
					rotacao.Y(cubo);
				}
				
				setDestino(matriz[0][2][0]);
				
				rotacao.L_(cubo);
				rotacao.U(cubo);
				rotacao.L(cubo);
			}
			//fim da etapa 5
			//*****************
			//etapa 6
			else{
				setDestino(matriz[0][2][0]);
				for(int i = 0; i < 4; i++){
					setDestino(matriz[1][0][0]);
					if(matriz[0][2][0].isCor(Cor.AZUL) ){//matriz[0][2][0].getKey() <= 8){
						if(!matriz[0][1][1].isCor(Cor.AZUL) ){//matriz[0][1][1].getKey() != 4){
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
					}
					else if(matriz[0][2][0].isCor(Cor.VERMELHO) ){//matriz[0][2][0].getKey() >= 9 && matriz[0][2][0].getKey() <= 17){
						if(!matriz[0][1][1].isCor(Cor.VERMELHO) ){//matriz[0][1][1].getKey() != 13){
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
					}
					else if(matriz[0][2][0].isCor(Cor.VERDE) ){//matriz[0][2][0].getKey() >= 18 && matriz[0][2][0].getKey() <= 26){
						if(!matriz[0][1][1].isCor(Cor.VERDE) ){//matriz[0][1][1].getKey() != 22){
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
					}
					else if(matriz[0][2][0].isCor(Cor.LARANJA) ){//matriz[0][2][0].getKey() >= 27 && matriz[0][2][0].getKey() <= 35){
						if(!matriz[0][1][1].isCor(Cor.LARANJA) ){//matriz[0][1][1].getKey() != 31){
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
					}
					rotacao.Y(cubo);
				}
			
			}
			//fim da etapa 6
			if(matriz[5][0][0].isCor(Cor.BRANCO) &&//matriz[5][0][0].getKey() >= 45 && 
					matriz[5][0][2].isCor(Cor.BRANCO) &&//matriz[5][0][2].getKey() >= 45 && 
					matriz[5][2][0].isCor(Cor.BRANCO) &&//matriz[5][2][0].getKey() >= 45 && 
					matriz[5][2][2].isCor(Cor.BRANCO) )//matriz[5][2][2].getKey() >= 45)
				flag = 1;
		}
		return;
	}
	
	/** Método que retorna os movimentos necessários para resolução da etapa Camada do Meio do 
	 * Cubo a partir de uma configuração recebida juntamente com a explicação necessária
	 */
	public  void resolveCamadaMeio(){
			resolveCantoInferior();
		    
			int flag=1, k=0;
			int cont=0;
			int flag2=0;
			int flag3=0;
			Adesivo[][][] matriz= cubo.getCubo();
			int x = 0;
				
			//TESTE PARA VER SE A CAMADA 2 está PRONTA
			while(flag!=0){
				
				flag=0;	
				if(/*matriz[0][1][1].isCor(Cor.AZUL)*/matriz[0][1][1].getKey() == 4){ //teste quando a face AZUL está para frente
					k=3;
					for(int i=0;i<4;i=i+2){		
						if((matriz[i][1][0].getKey() != k) ||(matriz[i][1][2].getKey() != k+2)){
							flag=1;
						}
						k=k+18;
					}
				}

				if(matriz[0][1][1].getKey() == 13){ //teste quando a face VERMELHA está para frente
					k=12;
					for(int i=0;i<4;i=i+2){		
						if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
							flag=1;
						}
						k=k+18;
					}
				}


				if(matriz[0][1][1].getKey() == 22){ //teste quando a face VERDE está para frente
					k=21;
					for(int i=0;i<4;i=i+2){		
						if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
							flag=1;
						}
						k=k-18;
					}
				}

				if(matriz[0][1][1].getKey() == 31){ //teste quando a face LARANJA está para frente
					k=30;
					for(int i=0;i<4;i=i+2){		
						if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
							flag=1;
						}
						k=k-18;
					}
				}
				//if(flag == 0) camada 2 está pronta
				//else camada 2 não está pronta

				//TESTE PARA VER SE TEM AMARELO NOS MEIOS DA CAMADA DE CIMA
				cont=0;
				if (flag==1){
					
						for(int j=0;j<4;j++){
							if(matriz[j][0][1].isCor(Cor.AMARELO)/*matriz[j][0][1].getKey() >= 36 && matriz[j][0][1] <=44*/)
								cont++;
						}
						if(matriz[4][0][1].isCor(Cor.AMARELO)/*matriz[4][0][1].getKey() >= 36 && matriz[4][0][1] <=44*/)
							cont++;
						if(matriz[4][1][0].isCor(Cor.AMARELO)/*matriz[4][1][0].getKey() >= 36 && matriz[4][1][0] <=44*/)
							cont++;
						if(matriz[4][1][2].isCor(Cor.AMARELO)/*matriz[4][1][2].getKey() >= 36 && matriz[4][1][2] <=44*/)
							cont++;
						if(matriz[4][2][1].isCor(Cor.AMARELO)/*matriz[4][2][1].getKey() >= 36 && matriz[4][2][1] <=44*/)
							cont++;
					
					//if(cont<4) alguma das pe�as do meio nao tem amarelo
					//else todas pe�as do meio possuem amarelo
				}

				//FAZENDO A SEGUNDA CAMADA
				if((cont<4)&&(flag==1)){
					flag2=0;
					
					setDestino(matriz[0][0][1]);
					
					while(matriz[0][0][1].isCor(Cor.AMARELO) ||/*enquanto for amarelo*/ /*matriz[0][0][1].getKey() >= 36 && matriz[0][0][1] <=44 ||  
							matriz[4][2][1].getKey() >= 36 && matriz[4][2][1] <=44*/
							matriz[4][2][1].isCor(Cor.AMARELO)){
						rotacao.U(cubo);
					}
					
					setDestino(matriz[0][0][1]);
					
					if((/*matriz[0][0][1].isCor(Cor.AZUL)*/matriz[0][0][1].getKey() == 3)||(matriz[0][0][1].getKey() == 5)){//se for azul
						
						if(!(matriz[0][1][1].isCor(Cor.AZUL)/*matriz[0][1][1].getKey() == 4*/)){
							setDestino(matriz[0][1][1]);
							
							while(!matriz[0][1][1].isCor(Cor.AZUL)/*matriz[0][1][1].getKey() != 4*/){//enquanto não for azul
								rotacao.D(cubo);
								rotacao.E(cubo);
							}
							
						}
						if(matriz[0][0][1].getKey() == 3)
							flag2=0;
						else
							if(matriz[0][0][1].getKey() == 5)
								flag2=1;
					}
					else{
						if(/*matriz[0][0][1].isCor(Cor.VERMELHO)*/(matriz[0][0][1].getKey() == 12)||(matriz[0][0][1].getKey() == 14)){//se for vermelho
							if(!(/*matriz[0][1][1].isCor(Cor.VERMELHO)*/matriz[0][1][1].getKey() == 13)){
								setDestino(matriz[0][1][1]);
								while(/*!matriz[0][1][1].isCor(Cor.VERDE)*/matriz[0][1][1].getKey() != 13){
									rotacao.D(cubo);
									rotacao.E(cubo);
								}
							}
							
							if(matriz[0][0][1].getKey() == 12)
								flag2=0;
							else
								if(matriz[0][0][1].getKey() == 14)
									flag2=1;
						}
						else{
							if(/*matriz[0][0][1].isCor(Cor.VERDE)*/(matriz[0][0][1].getKey() == 21)||(matriz[0][0][1].getKey() == 23)){
								if(!(/*matriz[0][1][1].isCor(Cor.VERDE)*/matriz[0][1][1].getKey() == 22)){
									setDestino(matriz[0][1][1]);
									while(/*!matriz[0][1][1].isCor(Cor.VERDE)*/matriz[0][1][1].getKey() != 22){
										rotacao.D(cubo);
										rotacao.E(cubo);
									}
								}
								if(matriz[0][0][1].getKey() == 21)
									flag2=0;
								else
									if(matriz[0][0][1].getKey() == 23)
										flag2=1;
							}
							else{
								if(/*matriz[0][0][1].isCor(Cor.LARANJA)*/(matriz[0][0][1].getKey() == 30)||(matriz[0][0][1].getKey() == 32)){
									if(!(matriz[0][1][1].isCor(Cor.LARANJA)/*matriz[0][1][1].getKey() == 31*/)){
										setDestino(matriz[0][1][1]);
										while(/*!matriz[0][1][1].isCor(Cor.LARANJA)*/matriz[0][1][1].getKey() != 31){
											rotacao.D(cubo);
											rotacao.E(cubo);
										}
									}
									if(matriz[0][0][1].getKey() == 30)
										flag2=0;
									else
										if(matriz[0][0][1].getKey() == 32)
											flag2=1;
								}
							}
						}
					}
					setDestino(matriz[4][2][1]);
					
					if(flag2==0){
						setDestino(matriz[1][1][1]);
						rotacao.U_(cubo);
						rotacao.L_(cubo);
						rotacao.U_(cubo);
						rotacao.L(cubo);
						rotacao.U(cubo);
						rotacao.Y_(cubo);
						rotacao.R(cubo);
						rotacao.U(cubo);
						rotacao.R_(cubo);
					}
					else{
						if(flag2==1){
							setDestino(matriz[3][1][1]);
							rotacao.U(cubo);
							rotacao.R(cubo);
							rotacao.U(cubo);
							rotacao.R_(cubo);
							rotacao.U_(cubo);
							rotacao.Y(cubo);
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
					}
				}
				else{
					//flag3=0;
					if((cont==4)&&(flag==1)){
						flag3=0;
						if(matriz[0][1][1].isCor(Cor.AZUL)/*matriz[0][1][1].getKey() == 4*/){ //verificando pecas erradas na face azul
							k=3;
							setOrigem(matriz[0][1][1]);
							
							for(int i=0;i<4;i=i+2){		
								if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){									
									
									if(matriz[i][1][0].getKey() != k && i==0)
										flag3=1;
									else
										if(matriz[i][1][2].getKey() != k+2 && i==0)
											flag3=0;
										else
											if(matriz[i][1][0].getKey() != k && i==2){
												flag3=1;
												
												setOrigem(matriz[i][1][0]);
												
												rotacao.Y(cubo);
												rotacao.Y(cubo);
											}
											else
												if(matriz[i][1][2].getKey() != k+2 && i==2){
													flag3=0;
													
													setOrigem(matriz[i][1][0]);
													
													rotacao.Y(cubo);
													rotacao.Y(cubo);
												}
								}
								k=k+18;
							}
						}

						if(matriz[0][1][1].isCor(Cor.VERMELHO)/*matriz[0][1][1].getKey() == 13*/){ //verificando pecas erradas na face vermelha
							k=12;
							setOrigem(matriz[0][1][1]);
							
							for(int i=0;i<4;i=i+2){		
								if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
									if(matriz[i][1][0].getKey() != k && i==0)
										flag3=1;
									else
										if(matriz[i][1][2].getKey() != k+2 && i==0)
											flag3=0;
										else
											if(matriz[i][1][0].getKey() != k && i==2){
												flag3=1;
												
												setOrigem(matriz[i][1][0]);

												rotacao.Y(cubo);
												rotacao.Y(cubo);
											}
											else
												if(matriz[i][1][2].getKey() != k+2 && i==2){
													flag3=0;
													
													setOrigem(matriz[i][1][0]);

													rotacao.Y(cubo);
													rotacao.Y(cubo);
												}
								}
								k=k+18;
							}
						}


						if(matriz[0][1][1].isCor(Cor.VERDE)/*matriz[0][1][1].getKey() == 22*/){ //verificando pecas erradas na face verde
							k=21;
							setOrigem(matriz[0][1][1]);
							for(int i=0;i<4;i=i+2){		
								if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
									if(matriz[i][1][0].getKey() != k && i==0)
										flag3=1;
									else
										if(matriz[i][1][2].getKey() != k+2 && i==0)
											flag3=0;
										else
											if(matriz[i][1][0].getKey() != k && i==2){
												flag3=1;
												
												setOrigem(matriz[i][1][0]);

												rotacao.Y(cubo);
												rotacao.Y(cubo);
											}
											else
												if(matriz[i][1][2].getKey() != k+2 && i==2){
													flag3=0;
													
													setOrigem(matriz[i][1][0]);

													rotacao.Y(cubo);
													rotacao.Y(cubo);
												}
								}
								k=k-18;
							}
						}

						if(matriz[0][1][1].getKey() == 31){ //verificando pecas erradas na face laranja
							k=30;
							setOrigem(matriz[0][1][1]);
							for(int i=0;i<4;i=i+2){		
								if((matriz[i][1][0].getKey() != k)||(matriz[i][1][2].getKey() != k+2)){
									if(matriz[i][1][0].getKey() != k && i==0)
										flag3=1;
									else
										if(matriz[i][1][2].getKey() != k+2 && i==0)
											flag3=0;
										else
											if(matriz[i][1][0].getKey() != k && i==2){
												flag3=1;
												setOrigem(matriz[i][1][0]);

												rotacao.Y(cubo);
												rotacao.Y(cubo);
											}
											else
												if(matriz[i][1][2].getKey() != k+2 && i==2){
													flag3=0;
													
													setOrigem(matriz[i][1][0]);

													rotacao.Y(cubo);
													rotacao.Y(cubo);
												}
								}
								k=k-18;
							}
						}
					
					if(flag3==1){
						rotacao.L_(cubo);
						rotacao.U_(cubo);
						rotacao.L(cubo);
						rotacao.U(cubo);
						rotacao.Y_(cubo);
						rotacao.R(cubo);
						rotacao.U(cubo);
						rotacao.R_(cubo);
					}
					else
						if(flag3==0){
							
							rotacao.R(cubo);
							rotacao.U(cubo);
							rotacao.R_(cubo);
							rotacao.U_(cubo);
							rotacao.Y(cubo);
							rotacao.L_(cubo);
							rotacao.U_(cubo);
							rotacao.L(cubo);
						}
						
					}
				}
			}
			return;
	}
	
	/** Método que retorna os movimentos necessários para resolução da etapa Cruz Superior do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	public void resolveCruzSuperior(){
		resolveCamadaMeio();
		Adesivo[][][] matriz = cubo.getCubo();
		int flag = 0;
		int contAmarelo = 0;
		int x = 0;
		if(matriz[4][0][1].isCor(Cor.AMARELO)/*matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44*/) 
			contAmarelo++;
		
		if(matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44)
			contAmarelo++;
		
		if(matriz[4][1][2].getKey() >= 36 && matriz[4][1][2].getKey() <= 44)
			contAmarelo++;
		
		if(matriz[4][2][1].getKey() >= 36 && matriz[4][2][1].getKey() <= 44)
			contAmarelo++;
		setOrigem(matriz[4][0][1]);
		setDestino(matriz[4][1][0]);
		setOrigemDois(matriz[4][1][2]);
		setDestinoDois(matriz[4][2][1]);
		
		if(contAmarelo == 4 ){
			return;
			///flag = 1;
		}
		
		///while(flag != 1){
			//etapa 1
			if(contAmarelo == 0){
				setOrigem(matriz[4][0][1]);
				setDestino(matriz[4][2][1]);
				
				rotacao.F(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U_(cubo);
				rotacao.R_(cubo);
				rotacao.F_(cubo);
				
				rotacao.U(cubo);
				setOrigem(matriz[4][0][1]);
				setDestino(matriz[4][1][0]);
				
				rotacao.F(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U_(cubo);
				rotacao.R_(cubo);
				rotacao.F_(cubo);
				
				setOrigem(matriz[4][1][2]);
				setDestino(matriz[4][2][1]);
				
				rotacao.F(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U_(cubo);
				rotacao.R_(cubo);
				rotacao.F_(cubo);
			} else{
				while( !( ( matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44 && //enquanto não for amarelo
						matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44 )  || 
						
						(matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44 && 
						 matriz[4][1][2].getKey() >= 36 && matriz[4][1][2].getKey() <= 44)) ) {
					
					rotacao.U(cubo);
				}
				if(matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44){
					setOrigem(matriz[4][0][1]);
					setDestino(matriz[4][1][0]);
					
					rotacao.F(cubo);
					rotacao.U(cubo);
					rotacao.R(cubo);
					rotacao.U_(cubo);
					rotacao.R_(cubo);
					rotacao.F_(cubo);
				}
				
				else{
					setOrigem(matriz[4][1][2]);
					setDestino(matriz[4][1][0]);
					
					rotacao.F(cubo);
					rotacao.U(cubo);
					rotacao.R(cubo);
					rotacao.U_(cubo);
					rotacao.R_(cubo);
					rotacao.F_(cubo);
					rotacao.F(cubo);
					rotacao.U(cubo);
					rotacao.R(cubo);
					rotacao.U_(cubo);
					rotacao.R_(cubo);
					rotacao.F_(cubo);
				}
			}
			
			contAmarelo = 0;
			
			if(matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44) 
				contAmarelo++;
			
			if(matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44)
				contAmarelo++;
			
			if(matriz[4][1][2].getKey() >= 36 && matriz[4][1][2].getKey() <= 44)
				contAmarelo++;
			
			if(matriz[4][2][1].getKey() >= 36 && matriz[4][2][1].getKey() <= 44)
				contAmarelo++;
			
			if(contAmarelo == 4 )
				flag = 1;
			
		//}
			//	cubo.executaSequencia(movs);
//			for (Iterator iter = movs.iterator(); iter.hasNext();) {
//				Integer element = (Integer) iter.next();
//				MovimentoCuboModel.passo(element.intValue());
//			}
		return;
	}
	
	/** Método que retorna os movimentos necessários para resolução da etapa Face Amarela do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	
	public  void resolveFaceAmarela(){
		resolveCruzSuperior();
		
		Adesivo[][][] matriz = cubo.getCubo();
		int flag = 0;
		int contAmarelo = 0;
		int x  =0;
		
		if(matriz[4][0][0].getKey() >= 36 && matriz[4][0][0].getKey() <= 44) 
			contAmarelo++;
		
		if(matriz[4][0][2].getKey() >= 36 && matriz[4][0][2].getKey() <= 44)
			contAmarelo++;
		
		if(matriz[4][2][0].getKey() >= 36 && matriz[4][2][0].getKey() <= 44)
			contAmarelo++;
		
		if(matriz[4][2][2].getKey() >= 36 && matriz[4][2][2].getKey() <= 44)
			contAmarelo++;
		
		if(contAmarelo == 4 )
			flag = 1;
		
		while(flag == 0){
			
			setDestino(matriz[3][0][2]);
			
			//etapa 1
			if(contAmarelo == 0){
				
				while(!matriz[3][0][2].isCor(Cor.AMARELO)/*matriz[3][0][2].getKey() < 36 || matriz[3][0][2].getKey() > 44*/){//enqunto não for amarelo
					rotacao.U(cubo);
				}
				setOrigem(matriz[4][2][2]);
				setDestino(matriz[4][0][0]);
				
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);		
			}
			
			else if (contAmarelo == 2){
				setDestino(matriz[0][0][0]);
				
				while(matriz[0][0][0].getKey() < 36 || matriz[0][0][0].getKey() > 44){
					//face amarela while 3
					rotacao.U(cubo);
				}
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
			} else {
				setDestino(matriz[4][2][0]);
				
				while(matriz[4][2][0].getKey() < 36 || matriz[4][2][0].getKey() > 44){
					rotacao.U(cubo);
				}
				
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
				rotacao.U(cubo);
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.U(cubo);
				rotacao.R_(cubo);
			}
			contAmarelo = 0;
			
			if(matriz[4][0][0].getKey() >= 36 && matriz[4][0][0].getKey() <= 44) 
				contAmarelo++;
			
			if(matriz[4][0][2].getKey() >= 36 && matriz[4][0][2].getKey() <= 44)
				contAmarelo++;
			
			if(matriz[4][2][0].getKey() >= 36 && matriz[4][2][0].getKey() <= 44)
				contAmarelo++;
			
			if(matriz[4][2][2].getKey() >= 36 && matriz[4][2][2].getKey() <= 44)
				contAmarelo++;
			
			if(contAmarelo == 4 )
				flag = 1;
		}
		return;
	}
	
	/** Método que retorna os movimentos necessários para resolução da etapa Canto Superior do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	public  void resolveCantoSuperior(){
		resolveFaceAmarela();
		
		Adesivo[][][] matriz = cubo.getCubo();
		int flag = 0;
		int x = 0;
		
		if( (matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor()) &
				(matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor()) &
				(matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor()) &
				(matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor())) {
			flag = 1;
		}
		
		while( flag != 1 ){
			//etapa 2 e 3
			if( (matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor()) | 
					(matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor()) |
					(matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor()) |
					(matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor())) {
				
				setOrigem(matriz[2][0][0]);
				setDestino(matriz[2][0][2]);
				
				while(!matriz[2][0][0].getCor().equals(matriz[2][0][2].getCor())){
					rotacao.U(cubo);
				}
				rotacao.R_(cubo);
				rotacao.F(cubo);
				rotacao.R_(cubo);
				rotacao.B(cubo);
				rotacao.B(cubo);
				rotacao.R(cubo);
				rotacao.F_(cubo);
				rotacao.R_(cubo);
				rotacao.B(cubo);
				rotacao.B(cubo);
				rotacao.R(cubo);
				rotacao.R(cubo);
			} else{
				rotacao.R_(cubo);
				rotacao.F(cubo);
				rotacao.R_(cubo);
				rotacao.B(cubo);
				rotacao.B(cubo);
				rotacao.R(cubo);
				rotacao.F_(cubo);
				rotacao.R_(cubo);
				rotacao.B(cubo);
				rotacao.B(cubo);
				rotacao.R(cubo);
				rotacao.R(cubo);
			}
			
			if( (matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor()) & 
					(matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor()) &
					(matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor()) &
					( matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor())) {
				flag = 1;
			}
		}
		return;
	} 
	
	/** Método que retorna os movimentos necessários para resolução da etapa Meio Superior do 
	 * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
	 */
	public  void resolveMeioSuperior(){ 
		resolveCantoSuperior();
		MainAuxiliar.Gravar(MainAuxiliar.arquivo_passo_anterior, "Cubo antes do último passo:");
		MainAuxiliar.Gravar(MainAuxiliar.arquivo_passo_anterior, cubo);
		
		Adesivo[][][] matriz = cubo.getCubo();
		int x = 0;
		//int flag = 0;
		while(true){
			setDestino(matriz[0][0][0]);
			setDestinoDois(matriz[0][0][2]);
			setOrigem(matriz[0][1][1]);
			while(!(matriz[0][0][0].getCor().equals(matriz[0][1][1].getCor()))) {
				rotacao.U(cubo);
			}
			if(matriz[0][0][0].getCor().equals(matriz[0][0][1].getCor()) && matriz[0][0][1].getCor().equals(matriz[0][0][2].getCor()) &&
			   matriz[1][0][0].getCor().equals(matriz[1][0][1].getCor()) && matriz[1][0][1].getCor().equals(matriz[1][0][2].getCor()) &
			   matriz[2][0][0].getCor().equals(matriz[2][0][1].getCor()) && matriz[2][0][1].getCor().equals(matriz[2][0][2].getCor()) &
			   matriz[3][0][0].getCor().equals(matriz[3][0][1].getCor()) && matriz[3][0][1].getCor().equals(matriz[3][0][2].getCor()) ){
				return;
			} else if(((matriz[0][0][0].getCor()).equals(matriz[0][0][1].getCor()) & matriz[0][0][1].getCor().equals(matriz[0][0][2].getCor())) |
					  ((matriz[1][0][0].getCor()).equals(matriz[1][0][1].getCor()) & matriz[1][0][1].getCor().equals(matriz[1][0][2].getCor())) | 
					  ((matriz[2][0][0].getCor()).equals(matriz[2][0][1].getCor()) & matriz[2][0][1].getCor().equals(matriz[2][0][2].getCor())) |
					  ((matriz[3][0][0].getCor()).equals(matriz[3][0][1].getCor()) & matriz[3][0][1].getCor().equals(matriz[3][0][2].getCor()))){
				setDestino(matriz[0][0][0]);
				setDestinoDois(matriz[0][0][2]);
				
				setOrigem(matriz[0][1][1]);
				
				while(!matriz[2][0][0].getCor().equals(matriz[2][0][1].getCor()) && !matriz[2][0][1].getCor().equals(matriz[2][0][2].getCor())){
					rotacao.Y(cubo);
				}
				
				if(matriz[0][0][1].getCor().equals(matriz[3][1][1].getCor())){
					setDestino(matriz[0][0][1]);
					setOrigem(matriz[3][1][1]);
					
					rotacao.F(cubo);
					rotacao.F(cubo);
					rotacao.U(cubo);
					rotacao.L(cubo);
					rotacao.R_(cubo);
					rotacao.F(cubo);
					rotacao.F(cubo);
					rotacao.L_(cubo);
					rotacao.R(cubo);
					rotacao.U(cubo);
					rotacao.F(cubo);
					rotacao.F(cubo);
				} else if(matriz[0][0][1].getCor().equals(matriz[1][1][1].getCor())){
					
					rotacao.F(cubo);
					rotacao.F(cubo);
					rotacao.U_(cubo);
					rotacao.L(cubo);
					rotacao.R_(cubo);
					rotacao.F(cubo);
					rotacao.F(cubo);
					rotacao.L_(cubo);
					rotacao.R(cubo);
					rotacao.U_(cubo);
					rotacao.F(cubo);
					rotacao.F(cubo);
					
					setDestino(matriz[0][0][1]);
					setOrigem(matriz[3][1][1]);
				}
			}
			else {
				rotacao.F(cubo);
				rotacao.F(cubo);
				rotacao.U(cubo);
				rotacao.L(cubo);
				rotacao.R_(cubo);
				rotacao.F(cubo);
				rotacao.F(cubo);
				rotacao.L_(cubo);
				rotacao.R(cubo);
				rotacao.U(cubo);
				rotacao.F(cubo);
				rotacao.F(cubo);
				setDestino(matriz[0][0][1]);
				setOrigem(matriz[1][1][1]);
			}
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void setCubo(CuboMagico3x3x3 cubo) {
		this.cubo = cubo;
	}
	
	public Adesivo getDestino() {
		return destino;
	}

	public void setDestino(Adesivo destino) {
		this.destino = destino;
	}

	public String getMensagem() {
		return mensagem;
	}

	public void setMensagem(String mensagem) {
		this.mensagem = mensagem;
	}

	public Adesivo getOrigem() {
		return origem;
	}

	public void setOrigem(Adesivo origem) {
		this.origem = origem;
	}

	public int getPasso() {
		return passo;
	}

	public void setPasso(int passo) {
		this.passo = passo;
	}

	public Adesivo getOrigemDois() {
		return origemDois;
	}

	public void setOrigemDois(Adesivo origemDois) {
		this.origemDois = origemDois;
	}

	public Adesivo getDestinoDois() {
		return destinoDois;
	}

	public void setDestinoDois(Adesivo destinoDois) {
		this.destinoDois = destinoDois;
	}
	
}